﻿using System;
using System . Collections . Generic;
using System . Linq;
using System . Text;
using System . Xml . Linq;

namespace WenceyWang . RichMan4L . Maps
{
	public class TRoad : Road
	{
		long firstExitID;

		Road firstExit = null;

		public virtual Road FirstExit { get { return firstExit ?? ( firstExit = Map . Currnet . GetRoad ( firstExitID ) ); } set { firstExitID = value . Id; firstExit = value; } }

		long secondExitID;

		Road secondExit = null;

		public virtual Road SecondExit { get { return secondExit ?? ( secondExit = Map . Currnet . GetRoad ( secondExitID ) ); } set { secondExitID = value . Id; secondExit = value; } }

		long thirdExitID;

		Road thirdExit = null;

		public virtual Road ThirdExit { get { return thirdExit ?? ( thirdExit = Map . Currnet . GetRoad ( thirdExitID ) ); } set { thirdExitID = value . Id; thirdExit = value; } }


		public override Path Route ( Road previous , int moveCount , Path result = null )
		{
			if ( previous == null )
			{
				throw new ArgumentNullException ( nameof ( previous ) );
			}
			if ( !CanEnter ( previous ) )
			{
				throw new ArgumentException ( "无法通过previous进入此道路" , nameof ( previous ) );
			}
			if ( moveCount < 0 )
			{
				throw new ArgumentOutOfRangeException ( nameof ( moveCount ) );
			}
			Path current = result ?? new Path ( );
			current . Route . Add ( this );
			if ( BlockMoving || moveCount == 0 )
			{
				return current;
			}
			else
			{
				List<Road> roadAvailable = new List<Road> ( );
				roadAvailable . Add ( FirstExit );
				roadAvailable . Add ( SecondExit );
				roadAvailable . Add ( ThirdExit );
				roadAvailable . Remove ( previous );
				roadAvailable . RemoveAll ( ( road ) => null == road );
				roadAvailable . RemoveAll ( ( road ) => !road . CanEnter ( this ) );
				Random random = new Random ( );
				return roadAvailable [ random . Next ( 0 , roadAvailable . Count ) ] . Route ( this , moveCount - 1 , result );
			}
		}

		public override bool CanEnter ( Road road )
		{
			List<Road> roadAvailable = new List<Road> ( );
			roadAvailable . Add ( FirstExit );
			roadAvailable . Add ( SecondExit );
			roadAvailable . Add ( ThirdExit );
			return roadAvailable . Contains ( road );
		}

		public TRoad ( XElement resource ) : base ( resource )
		{
			firstExitID = Convert . ToInt64 ( resource . Attribute ( nameof ( FirstExit ) ) . Value );
			secondExitID = Convert . ToInt64 ( resource . Attribute ( nameof ( SecondExit ) ) . Value );
			thirdExitID = Convert . ToInt64 ( resource . Attribute ( nameof ( ThirdExit ) ) . Value );
		}
	}
}
